var tgd = tgd || {};
tgd.Utilities = tgd.Utilities || {};
tgd.Utilities.Countdown = tgd.Utilities.Countdown || {};

/*
 * opts = { Title, EndDateTime }
 */
tgd.Utilities.Countdown.Timer = function (opts) {

	this._endDateTime = opts.EndDateTime;
	this._running = false;
	this.onUpdate = null;
	this.onTimerExpired = null;
	this._endDateTimeObject = new Date();
	this._title = (opts.Title == "" ? "Untitled Timer" : opts.Title);

	if (opts.EndDateTime.indexOf(":") > 0) {  //time
		this._endDateTimeObject.setHours(opts.EndDateTime.substr(0, opts.EndDateTime.indexOf(":")), opts.EndDateTime.substr(opts.EndDateTime.indexOf(":") + 1), 0, 0);
	} else {  //date
		var dateParts = opts.EndDateTime.split("/");
		this._endDateTimeObject.setFullYear(dateParts[2], dateParts[0] - 1, dateParts[1]);
		this._endDateTimeObject.setHours(0, 0, 0, 0);  //midnight
	}

	if (tgd.Utilities.Countdown.Timer._initialized === undefined) {

		/*
		 * The user input date or time, e.g. 17:00 or 1/29/2010
		 */
		tgd.Utilities.Countdown.Timer.prototype.getEndDateTime = function() {
			return this._endDateTime;
		}

		tgd.Utilities.Countdown.Timer.prototype.getEndDateTimeObject = function() {
			return this._endDateTimeObject;
		}

		tgd.Utilities.Countdown.Timer.prototype.getTitle = function() {
			return this._title;
		}

		tgd.Utilities.Countdown.Timer.prototype.start = function() {
			var self = this;

			if (!self._running) {
				self._running = true;
				var runTimer = function() {
					self._running = (self._running && (new Date()) < self._endDateTimeObject);
					self.onUpdate();

					if (self._running && self.onUpdate) {
						setTimeout(runTimer, 32);
					} else {
						self.onTimerExpired();
					}
				};
				setTimeout(runTimer, 32);
			}
		}

		tgd.Utilities.Countdown.Timer.prototype.stop = function() {
			this._running = false;
		}

		/*
		 * forTitle? : bool : optional : if true, show time remaining sans milliseconds and title
		 * otherwise show normal time remaining
		 */
		tgd.Utilities.Countdown.Timer.prototype.toString = function(forTitle) {
			forTitle = (forTitle !== undefined && forTitle);

			var _now = new Date();
			if (_now < this._endDateTimeObject) {
				var diff = this._endDateTimeObject.getTime() - _now.getTime();
				var days = Math.floor(diff / 86400000)
				var hours = Math.floor((diff - days * 86400000) / 3600000);
				var minutes = Math.floor((diff - days * 86400000 - hours * 3600000) / 60000);
				var seconds = Math.floor((diff - days * 86400000 - hours * 3600000 - minutes * 60000) / 1000);
				var milliseconds = Math.floor(diff - days * 86400000 - hours * 3600000 - minutes * 60000 - seconds * 1000);
				if (days > 0) {
					return days + " day" + (days == 1 ? "" : "s") + " " + (hours < 10 ? "0" : "") + hours + ":" + (minutes < 10 ? "0" : "") + minutes + ":" + (seconds < 10 ? "0" : "") + seconds + (forTitle ? " [" + this.getTitle() + "]" : "");
				} else {
					return (hours < 10 ? "0" : "") + hours + ":" + (minutes < 10 ? "0" : "") + minutes + ":" + (seconds < 10 ? "0" : "") + seconds  + (forTitle ? " [" + this.getTitle() + "]" : "." + (milliseconds < 100 ? "0" : "") + (milliseconds < 10 ? "0" : "") + milliseconds);
				}
			} else {
				return "Time's up!" + (forTitle ? " [" + this.getTitle() + "]" : "");
			}
		}

		tgd.Utilities.Countdown.Timer._initialized = true;
	}
};